/*
 * Copyright (C) 2013 tangzhi
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.tangzsoft.pdmviewer;

import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Toolkit;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Enumeration;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.event.TreeExpansionEvent;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.event.TreeWillExpandListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.ExpandVetoException;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
import org.tangzsoft.pdmviewer.model.PdmFile;
import org.tangzsoft.pdmviewer.model.PdmObject;
import org.tangzsoft.pdmviewer.model.impl.PdmFileImpl;
import org.tangzsoft.pdmviewer.model.impl.PdmObjectImpl;
import org.tangzsoft.pdmviewer.storage.PdmObjectDAO;
import org.tangzsoft.pdmviewer.storage.Storage;

/**
 * 主窗口上导航树的控制器
 * @author tangzhi
 */
public class NavTreeControler {
    
    private MainView mainView;
    
    private Storage storage =  PdmViewerContext.getInstance().getStorage();
    
    
    /**
     * 导航树
     */
    private JTree navTree;
    
    private DefaultMutableTreeNode rootNode;
    
    private DefaultTreeModel treeModel;
    
    private Toolkit toolkit = Toolkit.getDefaultToolkit();
    
    /**
     * 文件的三个状态:不在导航列表中,在导航列表中且打开,在导航列表中且关闭
     */
    public enum  FileState { NOEXISTS, OPEN, CLOSED };  
    
    
    /**
     * PdmObject对象比较器
     */
    private class PdmObjectComparator implements Comparator<PdmObject> {

        @Override
        public int compare(PdmObject o1, PdmObject o2) {
            if(o2==null) {
                return 1;
            }else if (o1==null) {
                return -1;
            }
            return o1.getName().compareTo(o2.getName());
        }
        
    };
    
    private TreeSelectionListener navTreeSelListener = new TreeSelectionListener() {

        @Override
        public void valueChanged(TreeSelectionEvent tse) {
            //TODO
            DefaultMutableTreeNode node = (DefaultMutableTreeNode) tse.getPath().getLastPathComponent();
            
            Object obj = node.getUserObject();
            
            if (obj instanceof PdmObject) {
                DefaultMutableTreeNode fileNode = (DefaultMutableTreeNode) node.getParent();
                PdmFile pdm = (PdmFile) fileNode.getUserObject();
                
                PdmObject o = (PdmObject) obj;
                
                mainView.vc.showPdmObjectView(pdm, o);
                
            }
            
        }
        
    };
    
    private TreeWillExpandListener navTreeWillExpand = new TreeWillExpandListener() {

        @Override
        public void treeWillExpand(TreeExpansionEvent event) throws ExpandVetoException {
            DefaultMutableTreeNode node = (DefaultMutableTreeNode) event.getPath().getLastPathComponent();
            
            Object obj = node.getUserObject();
            if (obj instanceof PdmFile && node.getChildCount() == 0) {
                PdmFile pdm = (PdmFile) obj;
                PdmObject[] diagrams = storage.getPdmObjectDAO().findDiagrams(pdm.getId());
                
                //按照diagram名称排序
                Arrays.sort(diagrams, new PdmObjectComparator());
                
                for(PdmObject o: diagrams) {
                    addObject(node, o);
                }
                
                //添加所有表
                PdmObject alltable = new PdmObjectImpl();
                alltable.setObjectId(PdmObjectDAO.ALL_TABLES);
                alltable.setName("All Tables");
                addObject(node, alltable);
                
                //TODO 添加所有序列、及其他对象

            }
            
        }

        @Override
        public void treeWillCollapse(TreeExpansionEvent event) throws ExpandVetoException {
            
        }
        
    };
    
    
    public NavTreeControler(MainView parent) {
        mainView = parent;
    }
    
    /**
     * 在容器内展现一颗树
     * @param parent Main窗口的pnlProject组件
     */
    public void initPdmViewerTree(Container parent) {
        
        parent.removeAll();
        
        parent.setLayout(new GridLayout(1,0));
        
        //List<Map<String,String>> files = storage.getPdmFileDAO().getAllPdmFiles();
        
        rootNode = new DefaultMutableTreeNode();
        treeModel = new DefaultTreeModel(rootNode);
        
        PdmFile pdm = new PdmFileImpl();
        pdm.setName("Welcome!");
        
        
        //rootNode.add(new DefaultMutableTreeNode(pdm));
        
        //navTree = new JTree(new Object[]{});
        navTree = new JTree(treeModel);
        navTree.setRootVisible(false);
        navTree.setEditable(false);
        navTree.setShowsRootHandles(true);
        
        navTree.addTreeWillExpandListener(navTreeWillExpand);
        
        //addObject(null, pdm);
        
        //设置图标
        //ImageIcon leafIcon;
        //leafIcon = Utils.createImageIcon(mainView.getClass(),"images/middle.gif");
        DefaultTreeCellRenderer renderer = new DefaultTreeCellRenderer();  
        //renderer.setLeafIcon(leafIcon);  
        //renderer.setOpenIcon(openIcon);
        //renderer.setClosedIcon(closedIcon);
        //navTree.setCellRenderer(renderer);
        
        navTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
        
        //
        
        
        
        //Listen for when the selection changes.
        navTree.addTreeSelectionListener(navTreeSelListener);
        
        JScrollPane splNavTree = new JScrollPane(navTree);
        Dimension minimumSize = new Dimension(80, 200);
        
        splNavTree.setMinimumSize(minimumSize);
        
        parent.add(splNavTree);
    }
    
    public FileState fileExists(String path) {
        TreeNode root = (TreeNode)navTree.getModel().getRoot();
        
        if(root.getChildCount()>0) {
            for(Enumeration e=root.children(); e.hasMoreElements();) {
                DefaultMutableTreeNode n = (DefaultMutableTreeNode)e.nextElement();
                PdmFile file = (PdmFile) n.getUserObject();
                if (path.equals(file.getPath())) {
                    if(n.getChildCount()>0) {
                        return FileState.OPEN;
                    }
                    else {
                        return FileState.CLOSED;
                    }
                }
            }
        }
        
        return FileState.NOEXISTS;
    }
    
    public DefaultMutableTreeNode addFile(PdmFile pdm) {
        
        DefaultMutableTreeNode fileNode = new DefaultMutableTreeNode(pdm) {
            @Override
            public boolean isLeaf() {
                return false;
            }
        };
        
        //添加子节点 采用懒加载方式
//        if (PdmFile.STATE_OPEN.equals(pdm.getState())) {
//            
//        }
        
        //新增的文件始终查找最前面
        treeModel.insertNodeInto(fileNode, rootNode, 0);
        navTree.scrollPathToVisible(new TreePath(fileNode.getPath()));
        
        return fileNode;
    }
    
    /**
     * 添加节点.
     * @param parent   父节点. e.g.当前选中节点 (DefaultMutableTreeNode)(tree.getSelectionPath().getLastPathComponent())
     * @param child
     * @return 
     */
    public DefaultMutableTreeNode addObject(DefaultMutableTreeNode parent,
                                            Object child) {
        return addObject(parent, child, false);
    }

    /**
     * 添加节点
     * @param parent
     * @param child
     * @param shouldBeVisible
     * @return 
     */
    public DefaultMutableTreeNode addObject(DefaultMutableTreeNode parent,
                                            Object child, 
                                            boolean shouldBeVisible) {
        DefaultMutableTreeNode childNode = 
                new DefaultMutableTreeNode(child);

        if (parent == null) {
            parent = rootNode;
        }
	
        //It is key to invoke this on the TreeModel, and NOT DefaultMutableTreeNode
        treeModel.insertNodeInto(childNode, parent, 
                                 parent.getChildCount());

        //Make sure the user can see the lovely new node.
        if (shouldBeVisible) {
            navTree.scrollPathToVisible(new TreePath(childNode.getPath()));
        }
        return childNode;
    }
    
    /** Remove the currently selected node. */
    public void removeCurrentNode() {
        TreePath currentSelection = navTree.getSelectionPath();
        if (currentSelection != null) {
            DefaultMutableTreeNode currentNode = (DefaultMutableTreeNode)
                         (currentSelection.getLastPathComponent());
            MutableTreeNode parent = (MutableTreeNode)(currentNode.getParent());
            if (parent != null) {
                treeModel.removeNodeFromParent(currentNode);
                return;
            }
        } 

        // Either there was no selection, or the root was selected.
        toolkit.beep();
    }
    
    /** Remove all nodes except the root node. */
    public void clear() {
        rootNode.removeAllChildren();
        treeModel.reload();
    }

}
